package com.yeskery.nut.websocket;

import net.sf.cglib.proxy.InvocationHandler;

import javax.websocket.MessageHandler;
import javax.websocket.Session;
import java.lang.reflect.Method;

/**
 * WebSocket Cglib动态代理拦截处理适配器
 * @author sprout
 * @version 1.0
 * 2023-04-16 12:25
 */
public class WebSocketCglibInvocationHandler implements InvocationHandler {

    /** WebSocket配置对象 */
    private final WebSocketConfiguration webSocketConfiguration;

    /**
     * 构建WebSocket Cglib动态代理拦截处理适配器
     * @param webSocketConfiguration WebSocket配置对象
     */
    public WebSocketCglibInvocationHandler(WebSocketConfiguration webSocketConfiguration) {
        this.webSocketConfiguration = webSocketConfiguration;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        WebSocketHandler webSocketHandler = webSocketConfiguration.getWebSocketHandler();
        switch (methodName) {
            case WebSocketHandler.ON_OPEN_METHOD_NAME:
                javax.websocket.Session session = (Session) args[0];
                JavaxWebSocketSession javaxWebSocketSession = new JavaxWebSocketSession(session);
                webSocketHandler.onOpen(javaxWebSocketSession);
                session.addMessageHandler(new MessageHandler.Whole<byte[]>() {
                    @Override
                    public void onMessage(byte[] bytes) {
                        webSocketHandler.onMessage(bytes, javaxWebSocketSession);
                    }
                });
                session.addMessageHandler(new MessageHandler.Whole<String>() {
                    @Override
                    public void onMessage(String text) {
                        webSocketHandler.onMessage(text, javaxWebSocketSession);
                    }
                });
                break;
            case WebSocketHandler.ON_CLOSE_METHOD_NAME:
                webSocketHandler.onClose(new JavaxWebSocketSession((Session) args[0]));
                break;
            case WebSocketHandler.ON_ERROR_METHOD_NAME:
                webSocketHandler.onError(new JavaxWebSocketSession((Session) args[0]), (Throwable) args[1]);
                break;
            default:
                method.invoke(proxy, args);
                break;
        }
        return null;
    }
}
